﻿// V1.0 - Versão inicial , programa responsavel por Calcular Expressões

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom.Compiler;

    class Program
    {
        static void Main()
        {
            string exp;

            Console.WriteLine("\nCalculadora de Expressao Versão 1.0\n");
                
            while (true) {

                Console.Write("Digite a expressao:");
                
                exp = Console.ReadLine();

                Console.Write("Resultado:");

                Console.WriteLine(Eval(exp));            
                
            }

        }

        public static string Eval(string code)
        {

            String result = String.Empty;

            if (code.IndexOf("return ") < 0)
                code = String.Format("return (float){0};", code.Replace(",", "."));

            try
            {
                Microsoft.CSharp.CSharpCodeProvider compiler = new Microsoft.CSharp.CSharpCodeProvider();

                string code_normalized = string.Format(

                @"using System;
              using System.Text;

              public static class Teste{{

                public static object Run(){{

                    try{{

                        {0}

                    }} catch (Exception ex) {{

                        return ex;

                    }}

                    return String.Empty;

                }}

            }}", code);

                CompilerResults resultcode = compiler.CompileAssemblyFromSource(new System.CodeDom.Compiler.CompilerParameters(),

                new string[] { code_normalized });

                if (resultcode.Errors.Count > 0)
                {
                    StringBuilder sb = new StringBuilder();

                    //sb.AppendLine("Compile erros:");

                    //sb.Append('=', 20);

                    //sb.AppendLine();


                    foreach (CompilerError var in resultcode.Errors)
                    {

                        //sb.AppendFormat("{0},{1}: {2}", var.Line, var.Column, var.ErrorNumber);

                        //sb.Clear();

                        sb.AppendFormat("{0}", var.ErrorText);

                        //sb.AppendLine();

                    }

                    result = sb.ToString();

                }
                else
                {

                    Type typeCompiled = resultcode.CompiledAssembly.GetType("Teste");

                    result = (typeCompiled.GetMethod("Run").Invoke(null, null) ?? String.Empty).ToString();

                }

            }
            catch (Exception ex)
            {

                result = ex.ToString();

            }

            return result;
        }
    }

